//数据类型和变量  DataTypesAndVariables

/*
Data Types:
undefined null boolean ,string ,symbol (不变的原始值 Symbol值表示唯一标识符。)
,number , and object
*/

/** 
var 和 let 第一点不同就是 let 是块作用域，即其在整个大括号 {} 之内可见。 

var：只有全局作用域和函数作用域概念，没有块级作用域的概念。但是会把{}内也假称为块作用域。

let：只有块级作用域的概念 ，由 { } 包括起来，if语句和for语句里面的{ }也属于块级作用域。

let 和 var 的第二点不同是，在变量声明之前就访问变量的话，会直接提示 ReferenceError，
而不像 var 那样使用默认值 undefined:

var 存在变量提升，而 let，const（后面会提及）声明的变量却不存在变量提升，
所以用 let 定义的变量一定要在声明后再使用，否则会报错。

ES6明确规定，如果区块中存在let命令，这个区块对这些命令声明的变量，从一开始就形成了封闭作用域。
凡是在声明之前就使用这些变量，就会报错。所以在代码块内，使用let命令声明变量之前，该变量都是不可用的。
这在语法上，称为“暂时性死区”（temporal dead zone，简称 TDZ）。

let a = 'outside';
if(true) {
   console.log(a);//Uncaught ReferenceError: a is not defined
    let a = "inside";
}
*/

var myname = " Bean"
let ourName = "Yihchangkong"
const pi = 3.14

//一、var声明的变量会挂载在window上，而let和const声明的变量不会

var a = 100;
console.log(a, window.a); // 100 100

let b = 10;
console.log(b, window.b); // 10 undefined

const c = 1;
console.log(c, window.c); // 1 undefined

// 二、 var声明变量存在变量提升， let和const不存在变量提升
console.log(a); // undefined  ===>  a已声明还没赋值，默认得到undefined值
var a = 100;

console.log(b); // 报错：b is not defined  ===> 找不到b这个变量
let b = 10;

console.log(c); // 报错：c is not defined  ===> 找不到c这个变量
const c = 10;

// 三、let和const声明形成块作用域
if (1) {
    var a = 100;
    let b = 10;
}

console.log(a); // 100
console.log(b) // 报错：b is not defined  ===> 找不到b这个变量

if (1) {

    var a = 100;

    const c = 1;
}
console.log(a); // 100
console.log(c) // 报错：c is not defined  ===> 找不到c这个变量


// 四、同一作用域下let和const不能声明同名变量，而var可以

var a = 100;
console.log(a); // 100

var a = 10;
console.log(a); // 10
let a = 100;
const a = 10;
//  控制台报错：Identifier 'a' has already been declared  ===> 标识符a已经被声明了。


// 五、暂存死区
var a = 100;

if (1) {
    a = 10;
    //在当前块作用域中存在a使用let/const声明的情况下，给a赋值10时，只会在当前作用域找变量a，
    // 而这时，还未到声明时候，所以控制台Error:a is not defined
    let a = 1;
}

// 六、const
/*
 * 　　1、一旦声明必须赋值,不能使用null占位。
 *
 * 　　2、声明后不能再修改
 *
 * 　　3、如果声明的是复合类型数据，可以修改其属性
 *
 * */

const a = 100;

const list = [];
list[0] = 10;
console.log(list);　　 // [10]

const obj = { a: 100 };
obj.name = 'apple';
obj.a = 10000;
console.log(obj);　　 // {a:10000,name:'apple'}